
# ifndef __DFX_CORE_PLUGIN_H__
# define __DFX_CORE_PLUGIN_H__

# include "dfxPlugin.h"
# include "dfxWindow.h"
# include "dfxThread.h"
# include "dfxMutex.h"
# include "dfxLog.h"
# include "dfxFile.h"
# include "dfxTimer.h"

namespace DFX
{
    extern "C"
    {
        typedef DFXRESULT (*WINDOWCREATE)(const String &name, const String &className, Window **window);
        typedef DFXRESULT (*REGISTERWINDOWCLASS)(const String &name);
        typedef DFXRESULT (*UNREGISTERWINDOWCLASS)(const String &name);
        typedef DFXRESULT (*PROCESSEVENTS)();
        typedef DFXRESULT (*FILECREATE)(const String &fileName, File **file);
        typedef DFXRESULT (*THREADCREATE)(PRIORITY priority, Thread **t);
        typedef DFXRESULT (*MUTEXCREATE)(Mutex **m);
        typedef DFXRESULT (*TIMERCREATE)(Timer **t);
    }

    class DFX_EXPORT CorePlugin : public Singleton<CorePlugin>, public Plugin
    {
    private:

        UInt32                  mHandle;
        String                  mDllFile;
        WINDOWCREATE            mWindowCreate;
        REGISTERWINDOWCLASS     mRegisterWindowClass;
        UNREGISTERWINDOWCLASS   mUnregisterWindowClass;
        PROCESSEVENTS           mProcessEvents;
        FILECREATE              mFileCreate;
        THREADCREATE            mThreadCreate;
        MUTEXCREATE             mMutexCreate;
        TIMERCREATE             mTimerCreate;

    public:

        CorePlugin(const String &dllFile);
        ~CorePlugin();

        const String& GetDllFile() const
        {
            return mDllFile;
        }

        DFXRESULT WindowCreate(const String &name, const String &className, Window **window);
        DFXRESULT RegisterWindowClass(const String &name);
        DFXRESULT UnregisterWindowClass(const String &name);
        
        DFXRESULT ProcessEvents();
        DFXRESULT FileCreate(const String &fileName, File **file);

        DFXRESULT ThreadCreate(PRIORITY priority, Thread **t);
        DFXRESULT MutexCreate(Mutex **m);
        DFXRESULT TimerCreate(Timer **t);

        DFXRESULT Load();
        DFXRESULT Unload();
    };
}

# endif